﻿/* Muaz Khan – http://dashingquill.web.officelive.com */
using System.Linq;
using System.Web.Mvc;
using DTweet.Helpers;
using DTweet.Models;
using System;

/***********************************
* One and only one controller!!
 * More than one controller in ASP.NET MVC degrades the performance!!
***********************************/

namespace DTweet.Controllers
{
    public class HomeController : Controller
    {
        readonly DatabaseEntities _db = new DatabaseEntities();

        public HomeController()
        {
            _db.ValidateCookie(); /* validate login cookies before any action execution! */
        }

        #region Home/About/Contact/Help/RSS
        
        /***********************************
         * Homepage
         ***********************************/
        public ActionResult Homepage()
        {
            return View(_db);
        }

        /***********************************
         * AboutUs
         ***********************************/
        public ActionResult AboutUs()
        {
            return View();
        }

        public ActionResult RSS(string userToken)
        {
            var user = userToken.GetAccountByUserToken(_db);
            var tweets = _db.Tweets.Where(t => t.UserToken == user.UniqueToken && t.SharedTo == "Public");
            return new RssResult(tweets.ToList(), user.FullName, _db);
        }

        #endregion

        #region Users related

        /***********************************
         * user page!
         ***********************************/        
        public ActionResult UserPage(string userToken, string fullName)
        {
            ViewBag.UserToken = userToken;
            ViewBag.FullName = fullName;
            return View(_db);
        }

        /***********************************
         * List of all public users
         ***********************************/
        public ActionResult UsersList()
        {
            return View(_db);
        }

        #endregion

        #region Accounts - AccountsHelperExtensions.cs

        /***********************************
         * Create Account
         ***********************************/
        public ActionResult Account()
        {
            return View();
        }

        /***********************************
         * Creating new Account
         ***********************************/
        [HttpPost]
        public JsonResult CreateAccount(string userName, string fullName, string password, string gravatar)
        {
            _db.CreateAccount(userName, fullName, password, gravatar);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true, token = Static.CurrentUser.UniqueToken });
        }

        /***********************************
         * Login [JSON Request]
         ***********************************/
        [HttpPost]
        public JsonResult Login(string userName, string password)
        {
            _db.Login(userName, password);
            return ErrorsHelper.IsError
                       ? Json(new { error = ErrorsHelper.ErrorMessage, success = false })
                       : Json(new { token = Static.CurrentUser.UniqueToken, success = true });
        }

        /***********************************
         * Logout
         ***********************************/
        [HttpPost, ValidateRequest]
        public JsonResult Logout()
        {
            try
            {
                Static.CurrentUser.LoginToken.RemoveCookie();
                return Json(true);
            }
            catch (Exception ex)
            {
                return Json(ex.Message);
            }
        }

        /***********************************
         * Account Settings
         ***********************************/
        [ValidateRequest]
        public ActionResult AccountSettings()
        {
            return View();
        }

        /***********************************
         * Save Account Settings
         ***********************************/
        [ValidateRequest, HttpPost]
        public JsonResult SaveAccountSettings(string fullName, string website, string about)
        {
            _db.SaveAccountSettings(fullName, website, about);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true });
        }

        #endregion

        #region Tweets - TweetsExtensions.cs

        /***********************************
         * tweet
         ***********************************/
        [HttpPost, ValidateRequest]
        public JsonResult Tweet(string message, string circles, string users)
        {
            var tweet = _db.AddTweet(message.Validate(), circles, users);
            var user = Static.CurrentUser;

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new
                {
                    IsSuccess = true,
                    message = tweet.Message.HandleAllThings(),
                    fullName = user.FullName,
                    userToken = user.UniqueToken,
                    tweetToken = tweet.TweetToken,
                    machineTime = tweet.TweetingTime.ToMachineTime(),
                    tweetingTime = tweet.TweetingTime + "",
                    postUrl = tweet.Message.FetchPostUrl()
                });
        }

        /***********************************
         * /tweet-tweetToken/userToken
         ***********************************/
        public ActionResult Status(string tweetToken, string postTitle)
        {
            _db.Status(tweetToken, postTitle);

            if (ErrorsHelper.IsError) return RedirectToAction("Homepage");

            ViewBag.Tweet = ResultHelper.Tweet;
            ViewBag.User = ResultHelper.User;
            
            return View(_db);
        }

        [ValidateRequest]
        public JsonResult GetForEdit(string id)
        {
            var tweet = _db.Tweets.Where(t => t.TweetToken == id && t.UserToken == Static.CurrentUser.UniqueToken).FirstOrDefault();
            if (tweet == null) return Json(new { IsSuccess = false, Error = "Post not found or you are not the owner!" });
            
            var tweetMessage = tweet.Message.ResolveForEdit();

            return Json(new { IsSuccess = true, tweetMessage });
        }

        [HttpPost, ValidateRequest]
        public JsonResult SubmitChanges(string id, string tweetMessage)
        {
            _db.SubmitChanges(id, tweetMessage);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true, tweetMessage = ResultHelper.TweetMessage });
        }

        #endregion       

        #region Circles - CirclesRelatedExtensions.cs

        [HttpPost, ValidateRequest]
        public JsonResult CreateCircle(string circleName, string userToken)
        {
            _db.CreateCircle(circleName, userToken);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true });
        }

        [HttpPost, ValidateRequest]
        public JsonResult InOrOutFromCircle(string circleName, string userToken)
        {
            _db.InOrOutFromCircle(circleName, userToken);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true, ResultHelper.InCircle, ResultHelper.FoundInAnyCircle });
        }

        [HttpPost, ValidateRequest]
        public JsonResult ValidatecircleOrUser(string value)
        {
            _db.ValidatecircleOrUser(value);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : ResultHelper.IsCircle
                    ? Json(new { IsSuccess = true, ResultHelper.IsCircle, ResultHelper.CircleName, ResultHelper.CircleToken })
                    : Json(new { IsSuccess = true, ResultHelper.IsUser, ResultHelper.UserFullName, ResultHelper.UserToken });
        }

        [ValidateRequest]
        public ActionResult Circles()
        {
            return View(_db);
        }

        [HttpPost, ValidateRequest]
        public JsonResult GetMembersFromCircle(string circleToken)
        {
            var circle = _db.GetMembersFromCircle(circleToken);
            if (circle == null) return Json(new { IsSuccess = false, Error = "Circle not found!" });

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true, circle.Members, circle.Tokens });
        }

        [HttpPost, ValidateRequest]
        public JsonResult UpdateCircleName(string circleName, string circleToken)
        {
            _db.UpdateCircleName(circleName, circleToken);

            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true });
        }

        [HttpPost, ValidateRequest]
        public JsonResult RemoveUserFromCircle(string circleToken, string userToken)
        {
            _db.RemoveUserFromCircle(circleToken, userToken);
            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true, ResultHelper.UserFullName });
        }

        [HttpPost, ValidateRequest]
        public JsonResult DeleteCircle(string circleToken)
        {
            _db.DeleteCircle(circleToken);
            return ErrorsHelper.IsError
                ? Json(new { IsSuccess = false, Error = ErrorsHelper.ErrorMessage })
                : Json(new { IsSuccess = true });
        }

        [HttpPost]
        public JsonResult GetFollowingOrFollowers(string userToken, string followingOrFollowers)
        {
            if (string.IsNullOrWhiteSpace(userToken) || string.IsNullOrWhiteSpace(followingOrFollowers))
                return Json(new { IsSuccess = false, Error = "Invalid request" });

            if (followingOrFollowers == "following")
            {
                return Json(new { IsSuccess = true, _db.GetUsersFromHisCircles(userToken).Members });
            }
            else
            {
                return Json(new { IsSuccess = true, _db.GetUsersFromHisCircles(userToken, isGetOtherUsersWhoCircledHim: true).Members });
            }
        }

        #endregion

        #region Delete post

        [HttpPost, ValidateRequest]
        public JsonResult DeletePost(string id)
        {
            var tweet = _db.Tweets.Where(t => t.TweetToken == id && t.UserToken == Static.CurrentUser.UniqueToken).FirstOrDefault();
            if (tweet == null) return Json("Post not found or you are not the owner!");
            try
            {
                _db.Tweets.DeleteObject(tweet);
                _db.SaveChanges();

                return Json(true);
            }
            catch (Exception ex)
            {
                return Json(ex.Message);
            }
        }

        #endregion        

        #region Delete Account Permanently

        [HttpPost, ValidateRequest]
        public JsonResult DeleteAccountPermanently(string securityToken)
        {
            var sToken = RandomNumbers.SecurityTokenForAccountDeleteRequest;
            if (sToken == null || string.IsNullOrWhiteSpace(sToken) || securityToken != sToken)
            {
                return Json(new { IsSuccess = false, Error = "Something went wrong. Please refresh the page and try again." });
            }

            var user = _db.Accounts.Where(a => a.UniqueToken == Static.CurrentUser.UniqueToken).FirstOrDefault();
            if (user == null) return Json(new { IsSuccess = false, Error = "Something went wrong. Please refresh the page and try again." });

            var allCirclesOfThisUser = _db.Circles.Where(c => c.UserToken == user.UniqueToken);
            if (allCirclesOfThisUser.Count() > 0)
            {
                foreach (var c in allCirclesOfThisUser)
                {
                    _db.DeleteObject(c);
                }
            }

            var allTweets = _db.Tweets.Where(t => t.UserToken == user.UniqueToken);
            if (allTweets.Count() > 0)
            {
                foreach (var t in allTweets)
                {
                    _db.DeleteObject(t);
                }
            }

            user.LoginToken.RemoveCookie();

            _db.DeleteObject(user);
            _db.SaveChanges();

            return Json(new { IsSuccess = true });
        }

        #endregion
    }
}